{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1 id = \"1\">1.Numpy简介</h1>\n",
    "\n",
    "> NumPy(Numerical Python) 是 Python 语言的一个扩展程序库，支持大量的维度数组与矩阵运算，此外也针对数组运算提供大量的数学函数库。\\\n",
    "NumPy 的前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发，2005 年，Travis Oliphant 在 Numeric 中结合了另一个同性质的程序库 Numarray 的特色，并加入了其它扩展而开发了 NumPy。NumPy 为开放源代码并且由许多协作者共同维护开发。\n",
    "\n",
    "NumPy 是一个运行速度非常快的数学库，主要用于数组计算，包含：\n",
    "- 一个强大的N维数组对象 ndarray\n",
    "- 广播功能函数\n",
    "- 整合 C/C++/Fortran 代码的工具\n",
    "- 线性代数、傅里叶变换、随机数生成等功能\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.Numpy安装\n",
    "### 2.1 使用`conda`安装\n",
    "```python\n",
    "conda install numpy\n",
    "```\n",
    "### 2.2 使用`pip`安装\n",
    "```python\n",
    "pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试是否安装成功\n",
    "import numpy as np\n",
    "np.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.Numpy Ndarry对象\n",
    "> NumPy 最重要的一个特点是其 N 维数组对象`ndarray`，它是一系列同类型数据的集合，以 0 下标为开始进行集合中元素的索引。\\\n",
    "ndarray 对象是用于存放同类型元素的多维数组。\\\n",
    "ndarray 中的每个元素在内存中都有相同存储大小的区域。\n",
    "\n",
    "### 3.1创建ndarray\n",
    "```python\n",
    "numpy.array(object, dtype = None, copy = True, order = 'K', subok = False, ndmin = 0, like=None)\n",
    "```\n",
    "参数说明：\n",
    "|  名称   | 描述  |\n",
    "|  ----  | ----  |\n",
    "| object  | 数组或嵌套的数列 |\n",
    "| dtype  | 数组元素的数据类型，可选 |\n",
    "| copy  | 对象是否需要复制，可选 |\n",
    "| order  | 创建数组的样式|\n",
    "| subok  | 默认返回一个与基类类型一致的数组 |\n",
    "| ndmin  | 指定生成数组的最小维度 |\n",
    "| like  | 引用对象以允许创建不是 NumPy数组的数组。如果传入的类似数组的 aslike支持__array_function__协议，则结果将由它定义。在这种情况下，它确保创建一个与通过此参数传入的对象兼容的数组对象。 版本 1.20.0 中的新功能。|\n",
    "\n",
    "</br>\n",
    "\n",
    "> **注意**:ndarry与array关系：ndarry是一个**类对象**，通过 **array()** 函数构造ndarry对象，也可以通过numpy.ndarray()构造函数构造ndarry对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 一维数组\n",
    "import numpy as np \n",
    "a = np.array([1,2,3])  \n",
    "print (\"a={},type(a)={}, a.shape={}\".format(a, type(a), a.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 二维数组\n",
    "import numpy as np \n",
    "a = np.array([[1],  [3]])  \n",
    "print (\"a={},type(a)={}, a.shape={}\".format(a, type(a), a.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 指定最小维度  \n",
    "import numpy as np \n",
    "a = np.array([1, 2, 3, 4, 5], ndmin =  2)  \n",
    "print (\"a={},type(a)={}, a.shape={}\".format(a, type(a), a.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dtype 参数  \n",
    "import numpy as np \n",
    "a = np.array([1,  2,  3], dtype = complex)  \n",
    "print (\"a={},type(a)={}, a.shape={}， type(a[0])={}\".format(a, type(a), a.shape, type(a[0])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dtype 参数  ## 1.\n",
    "import numpy as np \n",
    "a = np.array([1,  2,  3], dtype = complex)  \n",
    "print (\"a={},type(a)={}, a.shape={}， type(a[0])={}\".format(a, type(a), a.shape, type(a[0])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.Numpy 数据类型\n",
    "### 4.1Numpy数据类型\n",
    "> numpy 支持的数据类型比 Python 内置的类型要多很多，基本上可以和 C 语言的数据类型对应上，其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。\n",
    "\n",
    "参数说明：\n",
    "|  名称   | 描述  |\n",
    "|  ----  | ----  |\n",
    "|bool_\t|布尔型数据类型（True 或者 False）|\n",
    "|int_\t|默认的整数类型（类似于 C 语言中的 long，int32 或 int64）|\n",
    "|intc\t|与 C 的 int 类型一样，一般是 int32 或 int 64|\n",
    "|intp\t|用于索引的整数类型（类似于 C 的 ssize_t，一般情况下仍然是 int32 或 int64）|\n",
    "|int8\t|字节（-128 to 127）|\n",
    "|int16\t|整数（-32768 to 32767）|\n",
    "|int32\t|整数（-2147483648 to 2147483647）|\n",
    "|int64\t|整数（-9223372036854775808 to 9223372036854775807）|\n",
    "|uint8\t|无符号整数（0 to 255）|\n",
    "|uint16\t|无符号整数（0 to 65535）|\n",
    "|uint32\t|无符号整数（0 to 4294967295）|\n",
    "|uint64\t|无符号整数（0 to 18446744073709551615）|\n",
    "|float_\t|float64 类型的简写|\n",
    "|float16\t|半精度浮点数，包括：1 个符号位，5 个指数位，10 个尾数位|\n",
    "|float32\t|单精度浮点数，包括：1 个符号位，8 个指数位，23 个尾数位|\n",
    "|float64\t|双精度浮点数，包括：1 个符号位，11 个指数位，52 个尾数位|\n",
    "|complex_\t|complex128 类型的简写，即 128 位复数|\n",
    "|complex64\t|复数，表示双 32 位浮点数（实数部分和虚数部分）|\n",
    "|complex128\t|复数，表示双 64 位浮点数（实数部分和虚数部分）|\n",
    "\n",
    "每个内建类型都有一个唯一定义它的字符代码，如下：\n",
    "|  名称   | 描述  |\n",
    "|  ----  | ----  |\n",
    "|b\t|布尔型|\n",
    "|i\t|(有符号) 整型|\n",
    "|u\t|无符号整型 integer|\n",
    "|f\t|浮点型|\n",
    "|c\t|复数浮点型|\n",
    "|m\t|timedelta（时间间隔）|\n",
    "|M\t|datetime（日期时间）|\n",
    "|O\t|(Python) 对象|\n",
    "|S, a\t|(byte-)字符串|\n",
    "|U\t|Unicode|\n",
    "|V\t|原始数据 (void)|\n",
    "\n",
    "### 4.2数据类型对象（dtype）\n",
    "数据类型对象（numpy.dtype 类的实例）用来描述与数组对应的内存区域是如何使用，它描述了数据的以下几个方面：\n",
    "- 数据的类型（整数，浮点数或者 Python 对象）\n",
    "- 数据的大小（例如， 整数使用多少个字节存储）\n",
    "- 数据的字节顺序（小端法或大端法）\n",
    "- 在结构化类型的情况下，字段的名称、每个字段的数据类型和每个字段所取的内存块的部分\n",
    "- 如果数据类型是子数组，那么它的形状和数据类型是什么。\n",
    "\n",
    "字节顺序是通过对数据类型预先设定 **<** 或 **>** 来决定的。 < 意味着**小端法**(最小值存储在最小的地址，即低位组放在最前面)。> 意味着**大端法**(最重要的字节存储在最小的地址，即高位组放在最前面)。\n",
    "\n",
    "#### dtype对象构造\n",
    "```python\n",
    "numpy.dtype(object, align, copy)\n",
    "```\n",
    "- object - 要转换为的数据类型对象\n",
    "- align - 如果为 true，填充字段使其类似 C 的结构体。\n",
    "- copy - 复制 dtype 对象 ，如果为 false，则是对内置数据类型对象的引用\n",
    "\n",
    "### 4.3实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用标量类型\n",
    "import numpy as np\n",
    "dt = np.dtype(np.int32)\n",
    "print(dt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替\n",
    "import numpy as np\n",
    "dt = np.dtype('i4')\n",
    "print(dt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 字节顺序标注\n",
    "import numpy as np\n",
    "dt = np.dtype('<i4')\n",
    "print(dt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面实例展示结构化数据类型的使用，类型字段和对应的实际类型将被创建。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建结构化数据类型\n",
    "import numpy as np\n",
    "dt = np.dtype([('age',np.int8)]) \n",
    "print(dt)\n",
    "dt['age']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将数据类型应用于 ndarray 对象\n",
    "import numpy as np\n",
    "dt = np.dtype([('age',np.int8)]) \n",
    "a = np.array([(10,),(20,),(30,)], dtype = dt) \n",
    "print (\"a={},type(a)={}, a.shape={}\".format(a, type(a), a.shape))\n",
    "print(a['age'])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面的示例定义一个结构化数据类型 student，包含字符串字段 name，整数字段 age，及浮点字段 marks，并将这个 dtype 应用到 ndarray 对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "student = np.dtype([('name','S20'),('age','i1'),('marks','f4')])\n",
    "a = np.array([('joe',20,80),('susan',22,85),('tom',23,90),('fank',23,33)],dtype=student)\n",
    "print (\"a={},type(a)={}, a.shape={}\".format(a, type(a), a.shape))\n",
    "print(a['name'])\n",
    "print(a['age'])\n",
    "print(a['marks'])\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.Numpy数组属性\n",
    "> NumPy 数组的维数称为**秩（rank)**，秩就是轴的数量，即数组的维度，一维数组的秩为 1，二维数组的秩为 2，以此类推。\\\n",
    "在 NumPy中，每一个线性的数组称为是一个**轴（axis）**，也就是**维度（dimensions）**。比如说，二维数组相当于是两个一维数组，其中每一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴（axis），第一个轴相当于是底层数组，第二个轴是底层数组里的数组。而轴的数量——秩，就是数组的维数。\\\n",
    "很多时候可以声明 axis。axis=0，表示沿着第 0 轴进行操作，即对每一列进行操作；axis=1，表示沿着第1轴进行操作，即对每一行进行操作。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "NumPy 的数组中比较重要 ndarray 对象属性有：\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|ndarray.ndim | 秩，即轴的数量或维度的数量|\n",
    "|ndarray.shape | 数组的维度，对于矩阵，n 行 m 列|\n",
    "|ndarray.size | 数组元素的总个数，相当于 .shape 中 n*m 的值|\n",
    "|ndarray.dtype | ndarray 对象的元素类型|\n",
    "|ndarray.itemsize | ndarray 对象中每个元素的大小，以字节为单位|\n",
    "|ndarray.flags | ndarray 对象的内存信息|\n",
    "|ndarray.real | ndarray元素的实部|\n",
    "|ndarray.imag | ndarray 元素的虚部|\n",
    "|ndarray.data | 包含实际数组元素的缓冲区，由于一般通过数组的索引获取元素，所以通常不需要使用这个属性。|\n",
    "\n",
    "### 实例\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ndarray.shape, ndarry.reshape， ndarry.size\n",
    "import numpy as np\n",
    "a = np.array([\n",
    "    [[8], [9]],\n",
    "    [[10], [11]]\n",
    "])\n",
    "b = a.reshape(2, 2)\n",
    "c = a.reshape(4)\n",
    "print(\"a={},a.shape={},a.size={}\".format(a, a.shape,a.size))\n",
    "print(\"b={},b.shape={},a.size={}\".format(b, b.shape, b.size))\n",
    "print(\"c={},c.shape={}，c.size={}\".format(c, c.shape, c.size))\n",
    "import numpy as np \n",
    " \n",
    "s =  b'Hello World' \n",
    "a = np.frombuffer(s, dtype =  'S1')  \n",
    "print (a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ndarray.itemsize\n",
    "import numpy as np\n",
    "# 数组的 dtype 为 int8（一个字节）  \n",
    "x = np.array([1,2,3,4,5], dtype = np.int8)  \n",
    "print (x.itemsize)\n",
    " \n",
    "# 数组的 dtype 现在为 float64（八个字节） \n",
    "y = np.array([1,2,3,4,5], dtype = np.float64)  \n",
    "print (y.itemsize)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数组的 dtype 现在为 float64（八个字节） \n",
    "y = np.array([1+2j,2+3j,3+4j,4+5j,5+6j], dtype = np.complex64)  \n",
    "print (y)\n",
    "print (y[0].real,y[0].imag)\n",
    "print(y.real)\n",
    "print(y.imag)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.Numpy创建数组的几种方式\n",
    "### 6.1直接创建\n",
    "#### 6.1.1numpy.empty\n",
    "> numpy.empty 方法用来创建一个指定形状（shape）、数据类型（dtype）且**未初始化**的数组：\n",
    "\n",
    "```python\n",
    "numpy.empty(shape, dtype = float, order = 'C')\n",
    "```\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|shape |数组形状|\n",
    "|dtype |数据类型，可选|\n",
    "|order |有\"C\"和\"F\"两个选项,分别代表，行优先和列优先，在计算机内存中的存储元素的顺序。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    "x = np.empty([3,2], dtype = int) \n",
    "print (x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.1.2numpy.zeros\n",
    "> 创建指定大小的数组，数组元素以 **0** 来填充：\n",
    "\n",
    "```python\n",
    "numpy.zeros(shape, dtype = float, order = 'C')\n",
    "```\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|shape |数组形状|\n",
    "|dtype |数据类型，可选|\n",
    "|order |有\"C\"和\"F\"两个选项,分别代表，行优先和列优先，在计算机内存中的存储元素的顺序。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "# 默认为浮点数\n",
    "x = np.zeros(5) \n",
    "print(\"x={},x.dtype={}\".format(x, x.dtype))\n",
    " \n",
    "# 设置类型为整数\n",
    "y = np.zeros((5,), dtype = np.int8) \n",
    "print(y)\n",
    " \n",
    "# 自定义类型\n",
    "z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])  \n",
    "print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.1.3numpy.ones\n",
    "> 创建指定大小的数组，数组元素以 **1** 来填充：\n",
    "\n",
    "```python\n",
    "numpy.zeros(shape, dtype = float, order = 'C')\n",
    "```\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|shape |数组形状|\n",
    "|dtype |数据类型，可选|\n",
    "|order |有\"C\"和\"F\"两个选项,分别代表，行优先和列优先，在计算机内存中的存储元素的顺序。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "# 默认为浮点数\n",
    "x = np.ones(5) \n",
    "print(\"x={},x.dtype={}\".format(x, x.dtype))\n",
    " \n",
    "# 自定义类型\n",
    "x = np.ones([2,2], dtype = int)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.2从已有的数组创建数组\n",
    "#### 6.2.1numpy.asarray\n",
    "> numpy.asarray 类似 numpy.array，但 numpy.asarray 参数只有三个，比 numpy.array 少两个。\n",
    "\n",
    "```python\n",
    "numpy.asarray(a, dtype = None, order = None)\n",
    "```\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|a\t|任意形式的输入参数，可以是，列表, 列表的元组, 元组, 元组的元组, 元组的列表，多维数组|\n",
    "|dtype\t|数据类型，可选|\n",
    "|order\t|可选，有\"C\"和\"F\"两个选项,分别代表，行优先和列优先，在计算机内存中的存储元素的顺序。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将列表转换为 ndarray:\n",
    "import numpy as np \n",
    "x =  [1,2,3] \n",
    "a = np.asarray(x) \n",
    "print (\"type(x)={},a={},type(a)={}\".format(type(x), a, type(a)))\n",
    "\n",
    "# 将元组转换为 ndarray:\n",
    "y =  (1,2,3) \n",
    "b = np.asarray(x)  \n",
    "print (\"type(b)={},b={},type(b)={}\".format(type(y), b, type(b)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.2.2numpy.frombuffer\n",
    "> numpy.frombuffer 用于实现动态数组。\\\n",
    "numpy.frombuffer 接受 buffer 输入参数，以流的形式读入转化成 ndarray 对象。\n",
    "\n",
    "```python\n",
    "numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)\n",
    "```\n",
    "    注意：buffer 是字符串的时候，Python3 默认 str 是 Unicode 类型，所以要转成 bytestring 在原 str 前加上 b。\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|buffer\t|可以是任意对象，会以流的形式读入。|\n",
    "|dtype\t|返回数组的数据类型，可选|\n",
    "|count\t|读取的数据数量，默认为-1，读取所有数据。|\n",
    "|offset\t|读取的起始位置，默认为0。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    " \n",
    "s =  b'Hello World' \n",
    "a = np.frombuffer(s, dtype =  'S1')  \n",
    "print (a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.2.3numpy.fromiter\n",
    "> numpy.fromiter 方法从可迭代对象中建立 ndarray 对象，返回一维数组。\n",
    "\n",
    "```python\n",
    "numpy.fromiter(iterable, dtype, count=-1)\n",
    "```\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "iterable\t|可迭代对象|\n",
    "dtype\t|返回数组的数据类型|\n",
    "count\t|读取的数据数量，默认为-1，读取所有数据|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    " \n",
    "# 使用 range 函数创建列表对象  \n",
    "a=range(5)\n",
    "it=iter(a)\n",
    " \n",
    "# 使用迭代器创建 ndarray \n",
    "x=np.fromiter(it, dtype=float)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.3NumPy 从数值范围创建数组\n",
    "#### 6.3.1numpy.arange\n",
    "> numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象，函数格式如下\n",
    "\n",
    "```python\n",
    "numpy.arange(start, stop, step, dtype)\n",
    "```\n",
    "\n",
    "根据 start 与 stop 指定的范围以及 step 设定的步长，生成一个 ndarray。\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|start\t|起始值，默认为0|\n",
    "|stop\t|终止值（不包含）|\n",
    "|step\t|步长，默认为1|\n",
    "|dtype\t|返回ndarray的数据类型，如果没有提供，则会使用输入数据的类型。|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 设置了 dtype\n",
    "a = np.arange(5, dtype =  float)  \n",
    "b = np.arange(10,20,2)\n",
    "print (a)\n",
    "print (b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.3.2numpy.linspace\n",
    "> numpy.linspace 函数用于创建一个一维数组，数组是一个等差数列构成的，格式如下\n",
    "\n",
    "```python\n",
    "np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)\n",
    "```\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "start\t|序列的起始值|\n",
    "stop\t|序列的终止值，如果endpoint为true，该值包含于数列中|\n",
    "num\t|要生成的等步长的样本数量，默认为50|\n",
    "endpoint\t|该值为 true 时，数列中包含stop值，反之不包含，默认是True。|\n",
    "retstep\t|如果为 True 时，生成的数组中会显示间距，反之不显示。|\n",
    "dtype\t|ndarray 的数据类型|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "a = np.linspace(10, 20,  5)\n",
    "b = np.linspace(10, 20,  5, endpoint =  False) \n",
    "c = np.linspace(10, 20,  5, endpoint =  False, retstep = True) \n",
    "print(a)\n",
    "print(b)\n",
    "print(c)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "a = np.array([\n",
    "    [[8], [9]],\n",
    "    [[10], [11]]\n",
    "])\n",
    "print(\"a.shape={}\".format(a.shape))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6.3.3numpy.numpy.logspace\n",
    "> numpy.logspace 函数用于创建一个于等比数列。格式如下：\n",
    "\n",
    "```python\n",
    "np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)\n",
    "```\n",
    "base 参数意思是取对数的时候 log 的下标。\n",
    "\n",
    "$$\n",
    "log_{base}（y） = x => y = base^x\n",
    "$$\n",
    "\n",
    "| 属性 | 说明 |\n",
    "| --- | ---|\n",
    "|start\t|序列的起始值|\n",
    "|stop\t|序列的终止值，如果endpoint为true，该值包含于数列中|\n",
    "|num\t|要生成的等步长的样本数量，默认为50|\n",
    "|endpoint\t|该值为 true 时，数列中包含stop值，反之不包含，默认是True。|\n",
    "|base\t|对数 log 的底数。\n",
    "|dtype\t|ndarray 的数据类型|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 默认底数是 10\n",
    "a = np.logspace(1.0,  2.0, 10)  \n",
    "print (a)\n",
    "\n",
    "b = np.logspace(0,9,10,base=2)\n",
    "print (b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.Numpy切片和索引\n",
    "> ndarray对象的内容可以通过索引或切片来访问和修改，与 Python 中 list 的切片操作一样。\\\n",
    "ndarray 数组可以基于 0 - n 的下标进行索引，切片对象可以通过内置的 slice 函数，并设置 start, stop 及 step 参数进行，从原数组中切割出一个新数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(10)\n",
    "print(a)\n",
    "\n",
    "s = slice(2,7,2)   # 从索引 2 开始到索引 7 停止，间隔为2\n",
    "print (\"s={},a[s]={}\".format(s,a[s]))\n",
    "\n",
    "b = a[2:7:2]\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "冒号 : 的解释：如果只放置一个参数，如 [2]，将返回与该索引相对应的单个元素。如果为 [2:]，表示从该索引开始以后的所有项都将被提取。如果使用了两个参数，如 [2:7]，那么则提取两个索引(不包括停止索引)之间的项。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]\n",
    "b = a[5] \n",
    "print(\"b={}\".format(b))\n",
    "\n",
    "print(\"a[2:]={}\".format(a[2:]))\n",
    "print(\"a[2:5]={}\".format(a[2:5]))\n",
    "\n",
    "# 多维数组同样适用\n",
    "a = np.array([[1,2,3],[3,4,5],[4,5,6]])\n",
    "print(\"a={}\".format(a))\n",
    "print(\"a[1:]={}\".format(a[1:]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "切片还可以包括省略号 …，来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号，它将返回包含行中元素的 ndarray。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3],[3,4,5],[4,5,6]])  \n",
    "print (\"a[...,1]={}\".format(a[...,1]))   # 第2列元素\n",
    "print (\"a[1,...]={}\".format(a[1,...]))   # 第2行元素\n",
    "print (\"a[...,1:]={}\".format(a[...,1:]))  # 第2列及剩下的所有元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.Numpy高级索引\n",
    "> NumPy 比一般的 Python 序列提供更多的索引方式。除了之前看到的用整数和切片的索引外，数组可以由整数数组索引、布尔索引及花式索引。\n",
    "\n",
    "### 8.1整数数组索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以下实例获取数组中(0,0)，(1,1)和(2,0)位置处的元素。\n",
    "import numpy as np \n",
    " \n",
    "x = np.array([[1,  2],  [3,  4],  [5,  6]]) \n",
    "y = x[[0,1,2],  [0,1,0]]  \n",
    "print (y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以下实例获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3]，而列索引是 [0,2] 和 [0,2]。\n",
    "import numpy as np \n",
    " \n",
    "x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])  \n",
    "print ('我们的数组是：' )\n",
    "print (x)\n",
    "print ('\\n')\n",
    "rows = np.array([[0,0],[3,3]]) \n",
    "cols = np.array([[0,2],[0,2]]) \n",
    "y = x[rows,cols]  \n",
    "print  ('这个数组的四个角元素是：')\n",
    "print (y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 可以借助切片 : 或 … 与索引数组组合\n",
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3], [4,5,6],[7,8,9]])\n",
    "b = a[1:3, 1:3]\n",
    "c = a[1:3,[1,2]]\n",
    "d = a[...,1:]\n",
    "print(\"b={}\".format(b))\n",
    "print(\"c={}\".format(c))\n",
    "print(\"d={}\".format(d))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8.2布尔索引\n",
    "> 我们可以通过一个布尔数组来索引目标数组。\\\n",
    "布尔索引通过布尔运算（如：比较运算符）来获取符合指定条件的元素的数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以下实例获取大于 5 的元素：\n",
    "import numpy as np \n",
    " \n",
    "x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])  \n",
    "print ('我们的数组是：')\n",
    "print (x)\n",
    "print ('\\n')\n",
    "# 现在我们会打印出大于 5 的元素  \n",
    "print  ('大于 5 的元素是：')\n",
    "print (x[x >  5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以下实例演示如何从数组中过滤掉非复数元素。\n",
    "import numpy as np \n",
    " \n",
    "a = np.array([1,  2+6j,  5,  3.5+5j])  \n",
    "print (a[np.iscomplex(a)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8.3花式索引\n",
    "> 花式索引指的是利用整数数组进行索引。\\\n",
    "花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引，如果目标是一维数组，那么索引的结果就是对应下标的行，如果目标是二维数组，那么就是对应位置的元素。\\\n",
    "花式索引跟切片不一样，它总是将数据复制到新数组中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    "# 传入顺序索引数组\n",
    "x=np.arange(32).reshape((8,4))\n",
    "print(x)\n",
    "print (\"\\n\")\n",
    "print (x[[4,2,1,7]])\n",
    "print (\"\\n\")\n",
    "# 倒序索引数组\n",
    "print (x[[-4,-2,-1,-7]])\n",
    "print (\"\\n\")\n",
    "# 传入多个索引数组（要使用np.ix_）\n",
    "x=np.arange(32).reshape((8,4))\n",
    "print(np.ix_([1,5,7,2],[0,3,1,2]))\n",
    "print (x[np.ix_([1,5,7,2],[0,3,1,2])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9.NumPy 广播(Broadcast)\n",
    "> 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式， 对数组的算术运算通常在相应的元素上进行。\\\n",
    "如果两个数组 a 和 b 形状相同，即满足 a.shape == b.shape，那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同，且各维度的长度相同。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    " \n",
    "a = np.array([1,2,3,4]) \n",
    "b = np.array([10,20,30,40]) \n",
    "c = a * b \n",
    "print (c)\n",
    "\n",
    "print(\"\\n\")\n",
    "a = np.array([[ 0, 0, 0],\n",
    "           [10,10,10],\n",
    "           [20,20,20],\n",
    "           [30,30,30]])\n",
    "b = np.array([1,2,3])\n",
    "print(a + b)\n",
    "\n",
    "print(\"\\n\")\n",
    "# 4x3 的二维数组与长为 3 的一维数组相加，等效于把数组 b 在二维上重复 4 次再运算：\n",
    "b = np.array([1,2,3])\n",
    "bb = np.tile(b, (4, 1))  # 重复 b 的各个维度\n",
    "print(a + bb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面的图片展示了数组 b 如何通过广播来与数组 a 兼容。\n",
    "\n",
    "![image](https://note.youdao.com/yws/api/personal/file/WEB1bc6b2823451b4dbe355b802db8d5f78?method=download&shareKey=7a779e876d211e018ecf1d238404f312)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 广播的规则\n",
    "- 让所有输入数组都向其中形状最长的数组看齐，形状中不足的部分都通过在前面加 1 补齐。\n",
    "- 输出数组的形状是输入数组形状的各个维度上的最大值。\n",
    "- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时，这个数组能够用来计算，否则出错。\n",
    "- 当输入数组的某个维度的长度为 1 时，沿着此维度运算时都用此维度上的第一组值。\n",
    "\n",
    "**简单理解**：对两个数组，分别比较他们的每一个维度（若其中一个数组没有当前维度则忽略），满足：\n",
    "\n",
    "- 数组拥有相同形状。\n",
    "- 当前维度的值相等。\n",
    "- 当前维度的值有一个是 1。\n",
    "- 若条件不满足，抛出 \"ValueError: frames are not aligned\" 异常。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "a = np.array([[ 0, 0, 0],\n",
    "           [10,10,10],\n",
    "           [20,20,20],\n",
    "           [30,30,30]])\n",
    "b = np.array([1])\n",
    "print(a + b)\n",
    "\n",
    "c = np.array([1, 2])\n",
    "print(a + c) # 维度不一致"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 10.Numpy数组操作\n",
    "Numpy 中包含了一些函数用于处理数组，大概可分为以下几类：\n",
    "\n",
    "<li><font color=green>修改数组形状</font></li>\n",
    "<li><font color=green>转数组</font></li>\n",
    "<li><font color=green>修改数组维度</font></li>\n",
    "<li><font color=green>连接数组</font></li>\n",
    "<li><font color=green>分割数组</font></li>\n",
    "<li><font color=green>数组元素的添加与删除</font></li>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.1修改数组形状\n",
    "\n",
    "|函数|\t描述|\n",
    "|--- |--- |\n",
    "|reshape |\t不改变数据的条件下修改形状| \n",
    "|flat |\t数组元素迭代器| \n",
    "|flatten |\t返回一份数组拷贝，对拷贝所做的修改不会影响原始数组| \n",
    "|ravel |\t返回展开数组| "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.1.1numpy.reshape\n",
    "> numpy.reshape 函数可以在不改变数据的条件下修改形状\n",
    "\n",
    "```python\n",
    "numpy.reshape(arr, newshape, order='C')\n",
    "```\n",
    "\n",
    "- arr：要修改形状的数组\n",
    "- newshape：整数或者整数数组，新的形状应当兼容原有形状\n",
    "- order：'C' -- 按行，'F' -- 按列，'A' -- 原顺序，'k' -- 元素在内存中的出现顺序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(8)\n",
    "print ('原始数组：')\n",
    "print (a)\n",
    " \n",
    "b = a.reshape(4,2)\n",
    "print ('修改后的数组：')\n",
    "print (b)\n",
    "\n",
    "print ('修改后的数组：')\n",
    "c = np.reshape(a,[2, 4], order='F')\n",
    "print (c )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.1.2numpy.ndarray.flat\n",
    "> numpy.ndarray.flat 是一个数组元素迭代器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(9).reshape(3,3) \n",
    "print ('原始数组：')\n",
    "for row in a:\n",
    "    print (row)\n",
    " \n",
    "#对数组中每个元素都进行处理，可以使用flat属性，该属性是一个数组元素迭代器：\n",
    "print ('迭代后的数组：')\n",
    "for element in a.flat:\n",
    "    print (element)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.1.3numpy.ndarray.flatten\n",
    "> numpy.ndarray.flatten 返回一份数组拷贝，对拷贝所做的修改不会影响原始数组\n",
    "\n",
    "```python\n",
    "ndarray.flatten(order='C')\n",
    "```\n",
    "\n",
    "参数说明：\n",
    "- order：'C' -- 按行，'F' -- 按列，'A' -- 原顺序，'K' -- 元素在内存中的出现顺序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(8).reshape(2,4)\n",
    " \n",
    "print ('原数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    "# 默认按行\n",
    " \n",
    "print ('展开的数组：')\n",
    "print (a.flatten())\n",
    "print ('\\n')\n",
    " \n",
    "print ('以 F 风格顺序展开的数组：')\n",
    "print (a.flatten(order = 'F'))\n",
    "print ('\\n')\n",
    "\n",
    "b = a.flatten()\n",
    "print(a)\n",
    "print ('\\n')\n",
    "\n",
    "b[0] = 100\n",
    "print(a)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.1.4numpy.ravel\n",
    "> numpy.ravel() 展平的数组元素，顺序通常是\"C风格\"，返回的是数组视图，修改会影响原始数组。\n",
    "\n",
    "```python\n",
    "numpy.ravel(a, order='C')\n",
    "```\n",
    "\n",
    "参数说明：\n",
    "- order：'C' -- 按行，'F' -- 按列，'A' -- 原顺序，'K' -- 元素在内存中的出现顺序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(8).reshape(2,4)\n",
    " \n",
    "print ('原数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('调用 ravel 函数之后：')\n",
    "print (a.ravel())\n",
    "print ('\\n')\n",
    " \n",
    "print ('以 F 风格顺序调用 ravel 函数之后：')\n",
    "print (a.ravel(order = 'F'))\n",
    "print ('\\n')\n",
    "\n",
    "b = a.ravel()\n",
    "print(a)\n",
    "print ('\\n')\n",
    "\n",
    "b[0] = 100\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.2翻转数组\n",
    "\n",
    "|函数|\t描述|\n",
    "|--- |--- |\n",
    "|transpose\t| 对换数组的维度,即数组的转置|\n",
    "|ndarray.T\t| 和 transpose() 相同|\n",
    "|rollaxis\t| 向后滚动指定的轴|\n",
    "|swapaxes\t| 对换数组的两个轴|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.2.1numpy.transpose\n",
    "> numpy.transpose 函数用于对换数组的维度\n",
    "\n",
    "```python\n",
    "numpy.transpose(arr, axes)\n",
    "```\n",
    "\n",
    "参数说明:\n",
    "- arr：要操作的数组\n",
    "- axes：整数列表，对应维度，通常所有维度都会对换。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(12).reshape(3,4)\n",
    "b = np.arange(12).reshape(2,3,2)\n",
    "print ('原数组：')\n",
    "print (\"a={}\".format(a) )\n",
    "print ('\\n')\n",
    "print (\"b={}\".format(b) )\n",
    "print ('\\n')\n",
    "\n",
    "print ('对换数组：')\n",
    "print (\"np.transpose(a)=\\n{}\".format(np.transpose(a)))\n",
    "print ('\\n')\n",
    "print (\"np.transpose(b)=\\n{}\".format(np.transpose(b)))\n",
    "print ('\\n')\n",
    "\n",
    "c = np.transpose(b,(1, 0, 2)) \n",
    "print (\"c.shape=\\n{}\".format(c.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print ('对换数组：')\n",
    "print (\"a.T=\\n{}\".format(a.T))\n",
    "print ('\\n')\n",
    "print (\"b.T=\\n{}\".format(b.T))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "10.2.2numpy.rollaxis\n",
    "> numpy.rollaxis 函数向后滚动特定的轴到一个特定位置\n",
    "\n",
    "```python\n",
    "numpy.rollaxis(arr, axis, start)\n",
    "```\n",
    "\n",
    "参数说明：\n",
    "- arr：数组\n",
    "- axis：要向后滚动的轴，其它轴的相对位置不会改变\n",
    "- start：默认为零，表示完整的滚动。会滚动到特定位置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "# 创建了三维的 ndarray\n",
    "a = np.arange(8).reshape(2,2,2)\n",
    " \n",
    "print ('原数组：')\n",
    "print (a)\n",
    "print ('获取数组中一个值：')\n",
    "print(np.where(a==6))   \n",
    "print(a[1,1,0])  # 为 6\n",
    "print ('\\n')\n",
    " \n",
    " \n",
    "# 将轴 2 滚动到轴 0（宽度到深度）\n",
    " \n",
    "print ('调用 rollaxis 函数：')\n",
    "b = np.rollaxis(a,2,0)\n",
    "print (b)\n",
    "# 查看元素 a[1,1,0]，即 6 的坐标，变成 [0, 1, 1]\n",
    "# 最后一个 0 移动到最前面\n",
    "print(np.where(b==6))   \n",
    "print ('\\n')\n",
    " \n",
    "# 将轴 2 滚动到轴 1：（宽度到高度）\n",
    " \n",
    "print ('调用 rollaxis 函数：')\n",
    "c = np.rollaxis(a,2,1)\n",
    "print (c)\n",
    "# 查看元素 a[1,1,0]，即 6 的坐标，变成 [1, 0, 1]\n",
    "# 最后的 0 和 它前面的 1 对换位置\n",
    "# print(np.where(c==6))   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![image](https://note.youdao.com/yws/api/personal/file/WEBfe9aa098644aefc1fc66091b2f5fc0dc?method=download&shareKey=ad63857b47965db5587e181b53d4a511)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "10.2.3numpy.swapaxes\n",
    "> numpy.swapaxes 函数用于交换数组的两个轴，格式如下：\n",
    "\n",
    "numpy.swapaxes(arr, axis1, axis2)\n",
    "- arr：输入的数组\n",
    "- axis1：对应第一个轴的整数\n",
    "- axis2：对应第二个轴的整数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "# 创建了三维的 ndarray\n",
    "a = np.arange(6).reshape(1,2,3)\n",
    " \n",
    "print ('原数组：')\n",
    "print (a.shape)\n",
    "print ('\\n')\n",
    "# 现在交换轴 0（深度方向）到轴 2（宽度方向）\n",
    " \n",
    "print ('调用 swapaxes 函数后的数组：')\n",
    "print (np.swapaxes(a, 2, 1).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.3修改数组维度\n",
    "|维度\t|描述|\n",
    "| --- | --- |\n",
    "|broadcast|\t产生模仿广播的对象|\n",
    "|broadcast_to|\t将数组广播到新形状|\n",
    "|expand_dims|\t扩展数组的形状|\n",
    "|squeeze|从数组的形状中删除一维条目|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.3.1numpy.expand_dims\n",
    "> numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状，函数格式如下:\n",
    "```python\n",
    "numpy.expand_dims(arr, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：输入数组\n",
    "- axis：新轴插入的位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "x = np.array(([1,2],[3,4]))\n",
    " \n",
    "print ('数组 x：')\n",
    "print (x)\n",
    "print ('\\n')\n",
    "y = np.expand_dims(x, axis = 0)\n",
    " \n",
    "print ('数组 y：')\n",
    "print (y)\n",
    "print ('\\n')\n",
    "\n",
    "print ('x.ndim 和 y.ndim：')\n",
    "print (x.ndim,y.ndim)\n",
    "print ('\\n')\n",
    " \n",
    "print ('x.shape 和 y.shape：')\n",
    "print (x.shape, y.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.3.2numpy.squeeze\n",
    "> numpy.squeeze 函数从给定数组的形状中删除一维的条目，函数格式如下：\n",
    "```python\n",
    "numpy.squeeze(arr, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：输入数组\n",
    "- axis：整数或整数元组，用于选择形状中一维条目的子集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "x = np.arange(9).reshape(1,3,3)\n",
    " \n",
    "print ('数组 x：')\n",
    "print (x)\n",
    "print ('\\n')\n",
    "y = np.squeeze(x)\n",
    " \n",
    "print ('数组 y：')\n",
    "print (y)\n",
    "print ('\\n')\n",
    " \n",
    "print ('数组 x 和 y 的形状：')\n",
    "print (x.shape, y.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.4连接数组\n",
    "|函数\t|描述|\n",
    "| --- | --- |\n",
    "|concatenate|\t连接沿现有轴的数组序列|\n",
    "|stack\t|沿着新的轴加入一系列数组。|\n",
    "|hstack|水平堆叠序列中的数组（列方向）|\n",
    "|vstack|竖直堆叠序列中的数组（行方向）|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.4.1numpy.concatenate\n",
    "> numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组，格式如下：\n",
    "```python\n",
    "numpy.concatenate((a1, a2, ...), axis)\n",
    "````\n",
    "参数说明：\n",
    "\n",
    "- a1, a2, ...：相同类型的数组\n",
    "- axis：沿着它连接数组的轴，默认为 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2],[3,4]])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    "b = np.array([[5,6],[7,8]])\n",
    " \n",
    "print ('第二个数组：')\n",
    "print (b)\n",
    "print ('\\n')\n",
    "# 两个数组的维度相同\n",
    " \n",
    "print ('沿轴 0 连接两个数组：')\n",
    "print (np.concatenate((a,b)))\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 1 连接两个数组：')\n",
    "print (np.concatenate((a,b),axis = 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.4.2numpy.stack\n",
    "> numpy.stack 函数用于沿新轴连接数组序列，格式如下：\n",
    "```python\n",
    "numpy.stack(arrays, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arrays相同形状的数组序列\n",
    "- axis：返回数组中的轴，输入数组沿着它来堆叠"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2],[3,4]])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    "b = np.array([[5,6],[7,8]])\n",
    " \n",
    "print ('第二个数组：')\n",
    "print (b)\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 0 堆叠两个数组：')\n",
    "print (np.stack((a,b),0))\n",
    "print (np.stack((a,b),0).shape)\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 1 堆叠两个数组：')\n",
    "print (np.stack((a,b),1))\n",
    "print (np.stack((a,b),1).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.5分割数组\n",
    "|函数\t|数组及操作|\n",
    "| --- | --- |\n",
    "|split\t|将一个数组分割为多个子数组|\n",
    "|hsplit\t|将一个数组水平分割为多个子数组（按列）|\n",
    "|vsplit\t|将一个数组垂直分割为多个子数组（按行）|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.5.1numpy.split\n",
    "> numpy.split 函数沿特定的轴将数组分割为子数组，格式如下：\n",
    "```python\n",
    "numpy.split(ary, indices_or_sections, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- ary：被分割的数组\n",
    "- indices_or_sections：如果是一个整数，就用该数平均切分，如果是一个数组，为沿轴切分的位置（左开右闭）\n",
    "- axis：设置沿着哪个方向进行切分，默认为 0，横向切分，即水平方向。为 1 时，纵向切分，即竖直方向。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(9)\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('将数组分为三个大小相等的子数组：')\n",
    "b = np.split(a,3)\n",
    "print (b)\n",
    "print ('\\n')\n",
    " \n",
    "print ('将数组在一维数组中表明的位置分割：')\n",
    "b = np.split(a,[4,7])\n",
    "print (b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10.6数组元素的添加与删除\n",
    "|函数|\t元素及描述|\n",
    "| --- | --- |\n",
    "|resize|返回指定形状的新数组|\n",
    "|append|将值添加到数组末尾|\n",
    "|insert|沿指定轴将值插入到指定下标之前|\n",
    "|delete|删掉某个轴的子数组，并返回删除后的新数组|\n",
    "|unique|查找数组内的唯一元素|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.6.1numpy.resize\n",
    "> numpy.resize 函数返回指定大小的新数组。\\\n",
    "如果新数组大小大于原始大小，则包含原始数组中的元素的副本。\n",
    "\n",
    "```python\n",
    "numpy.resize(arr, shape)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：要修改大小的数组\n",
    "- shape：返回数组的新形状"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3],[4,5,6]])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('第一个数组的形状：')\n",
    "print (a.shape)\n",
    "print ('\\n')\n",
    "b = np.resize(a, (3,2))\n",
    " \n",
    "print ('第二个数组：')\n",
    "print (b)\n",
    "print ('\\n')\n",
    " \n",
    "print ('第二个数组的形状：')\n",
    "print (b.shape)\n",
    "print ('\\n')\n",
    "# 要注意 a 的第一行在 b 中重复出现，因为尺寸变大了\n",
    " \n",
    "print ('修改第二个数组的大小：')\n",
    "b = np.resize(a,(3,3))\n",
    "print (b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.6.2numpy.append\n",
    "> numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组，并把原来的数组复制到新数组中。 此外，输入数组的维度必须匹配否则将生成ValueError。\\\n",
    "append 函数返回的始终是一个一维数组。\n",
    "```python\n",
    "numpy.append(arr, values, axis=None)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：输入数组\n",
    "- values：要向arr添加的值，需要和arr形状相同（除了要添加的轴）\n",
    "- axis：默认为 None。当axis无定义时，是横向加成，返回总是为**一维数组**！当axis有定义的时候，分别为0和1的时候。当axi为0的时候,数组是加在右边（列数要相同）。当axis为1时，数组是加在右边（行数要相同）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2,3],[4,5,6]])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('向数组添加元素：')\n",
    "print (np.append(a, [7,8,9]))\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 0 添加元素：')\n",
    "print (np.append(a, [[7,8,9]],axis = 0))\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 1 添加元素：')\n",
    "print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.6.3numpy.insert\n",
    "> numpy.insert 函数在给定索引之前，沿给定轴在输入数组中插入值。\\\n",
    "如果值的类型转换为要插入，则它与输入数组不同。 插入没有原地的，函数会返回一个新数组。 此外，如果未提供轴，则输入数组会被展开。\n",
    "\n",
    "```python\n",
    "numpy.insert(arr, obj, values, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：输入数组\n",
    "- obj：在其之前插入值的索引\n",
    "- values：要插入的值\n",
    "- axis：沿着它插入的轴，如果未提供，则输入数组会被展开\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([[1,2],[3,4],[5,6]])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('未传递 Axis 参数。 在删除之前输入数组会被展开。')\n",
    "print (np.insert(a,3,[11,12]))\n",
    "print ('\\n')\n",
    "print ('传递了 Axis 参数。 会广播值数组来配输入数组。')\n",
    " \n",
    "print ('沿轴 0 广播：')\n",
    "print (np.insert(a,1,[11],axis = 0))\n",
    "print ('\\n')\n",
    " \n",
    "print ('沿轴 1 广播：')\n",
    "print (np.insert(a,1,11,axis = 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.6.4numpy.delete\n",
    "> numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样，如果未提供轴参数，则输入数组将展开。\n",
    "```python\n",
    "Numpy.delete(arr, obj, axis)\n",
    "```\n",
    "参数说明：\n",
    "\n",
    "- arr：输入数组\n",
    "- obj：可以被切片，整数或者整数数组，表明要从输入数组删除的子数组\n",
    "- axis：沿着它删除给定子数组的轴，如果未提供，则输入数组会被展开"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.arange(12).reshape(3,4)\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')\n",
    "print (np.delete(a,5))\n",
    "print ('\\n')\n",
    " \n",
    "print ('删除第二列：')\n",
    "print (np.delete(a,1,axis = 1))\n",
    "print ('\\n')\n",
    " \n",
    "print ('包含从数组中删除的替代值的切片：')\n",
    "a = np.array([1,2,3,4,5,6,7,8,9,10])\n",
    "print (a[::2])\n",
    "print (np.delete(a, np.s_[::2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.6.5numpy.unique\n",
    "> numpy.unique 函数用于去除数组中的重复元素。\n",
    "\n",
    "```python\n",
    "numpy.unique(arr, return_index, return_inverse, return_counts)\n",
    "````\n",
    "\n",
    "- arr：输入数组，如果不是一维数组则会展开\n",
    "- return_index：如果为true，返回新列表元素在旧列表中的位置（下标），并以列表形式储\n",
    "- return_inverse：如果为true，返回旧列表元素在新列表中的位置（下标），并以列表形式储\n",
    "- return_counts：如果为true，返回去重数组中的元素在原数组中的出现次数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    " \n",
    "a = np.array([5,2,6,2,7,5,6,8,2,9])\n",
    " \n",
    "print ('第一个数组：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('第一个数组的去重值：')\n",
    "u = np.unique(a)\n",
    "print (u)\n",
    "print ('\\n')\n",
    " \n",
    "print ('去重数组的索引数组：')\n",
    "u,indices = np.unique(a, return_index = True)\n",
    "print (indices)\n",
    "print ('\\n')\n",
    " \n",
    "print ('我们可以看到每个和原数组下标对应的数值：')\n",
    "print (a)\n",
    "print ('\\n')\n",
    " \n",
    "print ('去重数组的下标：')\n",
    "u,indices = np.unique(a,return_inverse = True)\n",
    "print (u)\n",
    "print ('\\n')\n",
    " \n",
    "print ('下标为：')\n",
    "print (indices)\n",
    "print ('\\n')\n",
    " \n",
    "print ('使用下标重构原数组：')\n",
    "print (u[indices])\n",
    "\n",
    "# print ('\\n')\n",
    " \n",
    "print ('返回去重元素的重复数量：')\n",
    "u,indices = np.unique(a,return_counts = True)\n",
    "print (u)\n",
    "print (indices)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 11.NumPy 字符串函数\n",
    "> 以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。\\\n",
    "这些函数在字符数组类（numpy.char）中定义。\n",
    "\n",
    "|函数|\t描述|\n",
    "| --- | --- |\n",
    "|add()|\t对两个数组的逐个字符串元素进行连接|\n",
    "|multiply()|\t返回按元素多重连接后的字符串|\n",
    "|center()|\t居中字符串|\n",
    "|capitalize()|\t将字符串第一个字母转换为大写|\n",
    "|title()|\t将字符串的每个单词的第一个字母转换为大写|\n",
    "|lower()|\t数组元素转换为小写|\n",
    "|upper()|\t数组元素转换为大写|\n",
    "|split()|\t指定分隔符对字符串进行分割，并返回数组列表|\n",
    "|splitlines()|\t返回元素中的行列表，以换行符分割|\n",
    "|strip()|\t移除元素开头或者结尾处的特定字符|\n",
    "|join()|\t通过指定分隔符来连接数组中的元素|\n",
    "|replace()|\t使用新字符串替换字符串中的所有子字符串|\n",
    "|decode()|\t数组元素依次调用str.decode|\n",
    "|encode()|\t数组元素依次调用str.encode|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 12.numpy数学函数\n",
    "### 三角函数\n",
    "> sin(),cos(),tan(),arcsin(),arxcos(),arctan()等\n",
    "\n",
    "### 舍入函数\n",
    "| 函数名|说明 |\n",
    "|---|---|\n",
    "|numpy.around() |函数返回指定数字的四舍五入值。|\n",
    "|numpy.floor() |numpy.floor() 返回小于或者等于指定表达式的最大整数，即向下取整。|\n",
    "|numpy.ceil()|numpy.ceil() 返回大于或者等于指定表达式的最小整数，即向上取整。|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 13.算术函数\n",
    "| 函数名| 说明|\n",
    "|---|---|\n",
    "|add()，subtract()，multiply() 和 divide()|加减乘除|\n",
    "|numpy.reciprocal()|返回参数逐元素的倒数|\n",
    "|numpy.power()|函数将第一个输入数组中的元素作为底数，计算它与第二个输入数组中相应元素的幂。|\n",
    "|numpy.mod()|计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。|\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 14.Numpy统计函数\n",
    "| 函数名| 说明|\n",
    "|---|---|\n",
    "|numpy.amin() | 用于计算数组中的元素沿指定轴的最小值。|\n",
    "|numpy.amax()|用于计算数组中的元素沿指定轴的最大值。|\n",
    "|numpy.ptp()|函数计算数组中元素最大值与最小值的差（最大值 - 最小值）|\n",
    "|numpy.percentile()|百分位数是统计中使用的度量，表示小于这个值的观察值的百分比|\n",
    "|numpy.median()|函数用于计算数组 a 中元素的中位数（中值）|\n",
    "|numpy.mean()|函数返回数组中元素的算术平均值。 如果提供了轴，则沿其计算|\n",
    "|numpy.average()| 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值|\n",
    "|std = sqrt(mean((x - x.mean())**2))|计算标准差|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 15.NumPy 排序\n",
    "\n",
    "#### numpy.sort()\n",
    "> numpy.sort() 函数返回输入数组的排序副本。函数格式如下：\n",
    "```python\n",
    "numpy.sort(a, axis, kind, order)\n",
    "```\n",
    "kind 类型有\n",
    "\n",
    "|种类\t|速度|\t最坏情况|\t工作空间|\t稳定性|\n",
    "|---|---|---|---|---|\n",
    "|'quicksort'（快速排序）|\t1|\tO(n^2)|\t0|\t否|\n",
    "|'mergesort'（归并排序）|\t2|\tO(n*log(n))|\t~n/2|\t是|\n",
    "|'heapsort'（堆排序）|\t3|\tO(n*log(n))|\t0|否|\n",
    "\n",
    "</br>\n",
    "\n",
    "|函数名|说明|\n",
    "|---|---|\n",
    "|numpy.argsort()|函数返回的是数组值从小到大的索引值。|\n",
    "|numpy.lexsort()|用于对多个序列进行排序|\n",
    "|numpy.argmax(),numpy.argmin()|numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。|\n",
    "|numpy.nonzero()|函数返回输入数组中非零元素的索引。|\n",
    "|numpy.where()|函数返回输入数组中满足给定条件的元素的索引。|\n",
    "|numpy.extract()|函数根据某个条件从数组中抽取元素，返回满条件的元素。|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 16.Numpy Matrix\n",
    "> NumPy 中包含了一个矩阵库 numpy.matlib，该模块中的函数返回的是一个矩阵，而不是 ndarray 对象。\n",
    "\n",
    "|函数名|说明|\n",
    "|---|---|\n",
    "|numpy.matlib.empty()|函数返回一个新的矩阵,其值是随机初始化|\n",
    "|numpy.matlib.zeros()|创建一个以 0 填充的矩阵|\n",
    "|numpy.matlib.ones()|创建一个以 1 填充的矩阵。|\n",
    "|numpy.matlib.eye()|函数返回一个矩阵，对角线元素为 1|\n",
    "|numpy.where()|函数返回输入数组中满足给定条件的元素的索引。|\n",
    "|numpy.extract()|函数根据某个条件从数组中抽取元素，返回满条件的元素。|\n",
    "|numpy.matlib.identity()|返回给定大小的单位矩阵。|\n",
    "|numpy.matlib.rand()|创建一个给定大小的矩阵，数据是随机填充的。|\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 17.线性代数\n",
    "\n",
    "|函数|\t描述|\n",
    "|---|---|\n",
    "|dot|\t两个数组的点积，即元素对应相乘。|\n",
    "|vdot|\t两个向量的点积|\n",
    "|inner|\t两个数组的内积|\n",
    "|matmul|\t两个数组的矩阵积|\n",
    "|determinant|\t数组的行列式|\n",
    "|solve|\t求解线性矩阵方程|\n",
    "|inv|\t计算矩阵的乘法逆矩阵|\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "44c4e092f96b2b920d29976b8c8137202660f31f9c00317fcf01cb244dfb630b"
  },
  "kernelspec": {
   "display_name": "Python 3.8.12 64-bit ('jupter': conda)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
